vim.g.coc_global_extensions = {
  'coc-marketplace',      -- 插件市场
  'coc-yank',             -- 剪切板历史
  'coc-lists',            -- 文件操作
  'coc-translator',       -- 翻译
  'coc-explorer',         -- 文件树
  'coc-highlight',        -- 显示颜色
  'coc-pairs',            -- 自动补全括号
  'coc-db',               -- 数据库
  'coc-wxml',             -- 小程序开发
  'coc-vimlsp',           -- vimscript
  'coc-json',             -- json
  'coc-snippets',         -- snippets
  'coc-emmet',            -- emmet
  'coc-tsserver',         -- typescript javascript
  'coc-webpack',          -- webpack
  -- 'coc-eslint',           -- eslint
  '@yaegassy/coc-volar',  -- vue3
  -- 'coc-vetur',
  'coc-html',             -- html
  'coc-css',              -- css
  'coc-html-css-support', -- html css class completion
  'coc-phpls',            -- php
  -- 'coc-java',
  'coc-pyright',          -- python
  'coc-clangd',           -- c c++
  'coc-flutter-tools',    -- dart flutter
  'coc-sql',              -- sql
  'coc-sh',               -- shell
  'coc-sumneko-lua',      -- lua
  'coc-git',              -- git
  -- 'coc-word',             -- word
  'coc-actions',          -- actions
  -- 'coc-symbol-line',      -- winbar
  -- "coc-react-refactor",  -- react
  -- '@yaegassy/coc-marksman',    -- markdown
  -- 'coc-simple-react-snippets', -- react 代码片段
  -- '@yaegassy/coc-volar-tools', -- vue3
  -- 'coc-prettier', -- typescript and javascript 格式化
}

function _G.check_back_space()
  local col = vim.fn.col('.') - 1
  return col == 0 or vim.fn.getline('.'):sub(col, col):match('%s') ~= nil
end

local function show_docs()
  local cw = vim.fn.expand('<cword>')
  if vim.fn.index({ 'vim', 'help' }, vim.bo.filetype) >= 0 then
    vim.api.nvim_command('h ' .. cw)
  elseif vim.api.nvim_eval('coc#rpc#ready()') then
    vim.fn.CocActionAsync('doHover')
  else
    vim.api.nvim_command('!' .. vim.o.keywordprg .. ' ' .. cw)
  end
end
-- CocOutline
local function ToggleOutline()
  local winid = vim.api.nvim_eval("coc#window#find('cocViewId', 'OUTLINE')")
  if winid == -1 then
    vim.fn.CocActionAsync('showOutline', 1)
  else
    vim.cmd [[call coc#window#close(coc#window#find('cocViewId', 'OUTLINE'))]]
  end
end

local keyset = vim.keymap.set
local opts = { silent = true, noremap = true, expr = true, replace_keycodes = false }
local opts_codeaction = { silent = true, nowait = true }
local opts_ = { silent = true, nowait = true }
local map = {
  -- ai
  { "i", "<C-e>",      'codeium#Accept()',  opts },
  { "n", "<leader>co", ':Codeium Chat<CR>', { silent = true } },
  -- coc
  {
    "i",
    "<TAB>",
    'coc#pum#visible() ? coc#pum#next(1) : v:lua.check_back_space() ? "<TAB>" : coc#refresh()',
    opts
  },
  { "i", "<S-TAB>",    [[coc#pum#visible() ? coc#pum#prev(1) : "\<C-h>"]],      opts },
  -- 回车补全
  { "i", "<cr>",       [[coc#pum#visible() ? coc#_select_confirm() : "\<CR>"]], opts },
  -- 跳出补全
  { "i", "<c-o>",      "coc#refresh()",                                         { silent = true, expr = true } },
  { "n", "K",          show_docs,                                               { silent = true } },
  -- 查找上一个和下一个代码报错
  { "n", "[<space>",   "<Plug>(coc-diagnostic-prev)",                           { silent = true } },
  { "n", "]<space>",   "<Plug>(coc-diagnostic-next)",                           { silent = true } },
  --  跳转到函数或者变量调用的地方
  { "n", "gd",         "<Plug>(coc-definition)",                                { silent = true } },
  { "n", "gi",         "<Plug>(coc-implementation)",                            { silent = true } },
  -- 查看函数或者变量在哪调用过
  { "n", "gy",         "<Plug>(coc-type-definition)",                           { silent = true } },
  { "n", "gr",         "<Plug>(coc-references)",                                { silent = true } },
  -- 重命名
  { "n", "<leader>w",  "<Plug>(coc-rename)",                                    { silent = true } },
  -- 代码格式化
  { "x", "<leader>f",  "<Plug>(coc-format-selected)",                           { silent = true } },
  { "n", "<leader>f",  "<Plug>(coc-format-selected)",                           { silent = true } },
  -- 将codeAction应用于所选区域。
  { "x", "<leader>a",  "<Plug>(coc-codeaction-selected)",                       opts_codeaction },
  { "n", "<leader>a",  "<Plug>(coc-codeaction-selected)w",                      opts_codeaction },
  -- 查看诊断
  { "n", "<leader>gf", "<Plug>(coc-codeaction-cursor)",                         opts_codeaction },
  -- 自动诊断
  { "n", "<leader>qf", "<Plug>(coc-fix-current)",                               opts_codeaction },
  -- CocList
  { "n", "cs",         ":CocList<CR>",                                          opts_ },
  { "n", "s;",         ":CocList --auto-preview diagnostics<cr>",               opts_ },
  --  CocDiagnostics
  { "n", "<leader>ge", ":CocDiagnostics<CR>",                                   opts_ },
  -- CocCommand
  { "n", "cm",         ":CocCommand<CR>",                                       opts_ },
  -- 代码重构
  { "n", "<leader>rf", "<Plug>(coc-refactor)",                                  opts_ },
  -- coc-translator 可以看英语单词的意思(也可以看中文的英文翻译)
  { "n", "ts",         "<Plug>(coc-translator-p)",                              { silent = true } },
  { "x", "ts",         "<Plug>(coc-translator-pv)",                             { silent = true } },
  --  coc-yank
  { "n", "<leader>y",  ":CocList --auto-preview yank<CR>",                      { silent = true } },
  --  查看coc语法高亮组
  { "n", "<F10>",      ":CocCommand semanticTokens.inspect<CR>",                { silent = true } },
  -- coc-git
  { "n", "<space>gk",  "<Plug>(coc-git-prevchunk)",                             { silent = true } },
  { "n", "<space>gj",  "<Plug>(coc-git-nextchunk)",                             { silent = true } },
  -- " 查看当前git修改
  { "n", "gs",         "<Plug>(coc-git-chunkinfo)",                             { silent = true } },
  -- 查看git提交内容
  { "n", "<space>K",   "<Plug>(coc-git-commit)",                                { silent = true } },
  -- 选中当前git修改区域
  { "x", "ig",         "<Plug>(coc-git-chunk-inner)",                           { silent = true } },
  { "x", "ag",         "<Plug>(coc-git-chunk-outer)",                           { silent = true } },
  -- coc文件件树
  { "n", "sv",         ":CocCommand explorer<CR>",                              { silent = true } },
  -- CocOutline
  -- { "n", "se",         ToggleOutline,                                           { silent = true } },
  { "n", "<space>H",   ":call CocActionAsync('highlight')<CR>",                 { silent = true } },
}

vim.api.nvim_create_augroup("_CocGroup", {})
-- autocmd
local autocmd = {
  {
    "CursorMoved",
    "_CocGroup",
    "",
    "silent call CocActionAsync('highlight')",
    "Highlight symbol under cursor on CursorHold"
  },
  {
    "FileType",
    "_CocGroup",
    "typescript,json",
    "setl formatexpr=CocAction('formatSelected')",
    "Setup formatexpr specified filetype(s)."
  },
  {
    "User",
    "_CocGroup",
    "CocJumpPlaceholder",
    "call CocActionAsync('showSignatureHelp')",
    "Update signature help on jump placeholder"
  },
}
-- highlight
local CocTextHighlight = {
  "CocHighlightRead",
  "CocHighlightWrite",
  "CocHighlightText",
}
vim.api.nvim_set_hl(0, "IlluminatedWordText", {
  link = "illuminatedWord"
})

-- command
local coc_command = {
  { "Format",        "call CocAction('format')",                                          {} },
  { "Fold",          "call CocAction('fold', <f-args>)",                                  { nargs = '?' } },
  { "OR",            "call CocActionAsync('runCommand', 'editor.action.organizeImport')", {} },
  { "ToggleOutline", ToggleOutline,                                                       {} },
}

local function Deploy(opt, name)
  for _key, value in pairs(opt) do
    if name == "map" then
      keyset(value[1], value[2], value[3], value[4])
    elseif name == "autocmd" then
      vim.api.nvim_create_autocmd(value[1], {
        group = value[2],
        pattern = value[3],
        command = value[4],
        desc = value[5]
      })
    elseif name == "highlight" then
      -- 链接一个已有的高亮组到新定义的高亮组
      vim.api.nvim_set_hl(0, value, {
        link = "IlluminatedWordText"
      })
    elseif name == "command" then
      vim.api.nvim_create_user_command(value[1], value[2], value[3])
    end
  end
end
Deploy(map, "map")
Deploy(autocmd, "autocmd")
Deploy(CocTextHighlight, "highlight")
Deploy(coc_command, "command")


vim.cmd [[
" ===
" === Vista.vim
" ===
noremap se :Vista!!<CR>
let g:vista_icon_indent = ["󱍵 ", "󰆤 "]
let g:vista_default_executive = 'coc'
let g:vista_fzf_preview = ['right:50%']
let g:vista#renderer#enable_icon = 1
let g:vista#renderer#icons = {
\ "keyword"       : "",
\ "variable"      : "",
\ "operator"      : "",
\ "function"      : "",
\ "method"        : "",
\ "reference"     : "",
\ "constant"      : "",
\ "struct"        : "",
\ "class"         : "",
\ "interface"     : "",
\ "text"          : "",
\ "enum"          : "",
\ "enumMember"    : "",
\ "module"        : "",
\ "color"         : "",
\ "property"      : "",
\ "field"         : "",
\ "file"          : "",
\ "folder"        : "",
\ "snippet"       : "",
\ "typeParameter" : "",
\ "constructor"   : "",
\ "default"       : "",
\ "event"         : "",
\ "unit"          : "",
\ "value"         : ""
\}
]]

vim.cmd [[
" coc
source $HOME/.config/nvim/highlight/hi.vim
]]
